/**
 * Copyright (c) 2010 sonntagsfarben.de
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
package de.sonntagsfarben.display
{
	import de.sonntagsfarben.events.CoreEvent;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;

	/**
	 * @author Soenke Kluth <sonntagsfarben.de>
	 * @copyright (c) 2010 Soenke Kluth.
	 */
	
	[Event(name="stateChanged", type="de.sonntagsfarben.events.CoreEvent")]
	
	public class CoreSprite extends Sprite
	{
		protected var _state : *;
		protected var _enabled : Boolean = true;
		private var _destroyed : Boolean;
		private var _resizeHandler : Function;
		public var destroyOnRemove : Boolean = false;

		public function CoreSprite()
		{
			_addListener();
		}

		
		/****************************************
		 *				PRIVATE / PROTECTED
		 ****************************************/
		private function _addListener() : void
		{
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
			addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage, false, 0, true);
		}

		
		/****************************************
		 *				EVENT-HANDLER
		 ****************************************/
		protected function onAddedToStage(event : Event) : void
		{
			if(_resizeHandler != null)
           		stage.addEventListener(Event.RESIZE, _resizeHandler, false, 0, true);
			try {
				updateView();
			}catch(e : Error) {
			}
		}

		
		protected function onRemovedFromStage(event : Event) : void
		{
			if(destroyOnRemove && !_destroyed)
        		destroy();
		}

		
		/****************************************
		 *				PUBLIC 
		 ****************************************/
		public function dispatchCoreEvent(type : String, data : *, bubbles : Boolean = false, cancleable : Boolean = false) : void
		{
			dispatchEvent(new CoreEvent(type, data, bubbles, cancleable));
		}

		
		public function destroy() : void
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
			if(_resizeHandler != null && stage)
           		stage.removeEventListener(Event.RESIZE, _resizeHandler);
			_destroyed = true;
		}

		
		public function setSize(width : Number, height : Number) : void
		{
			this.width = width;
			this.height = height;
		}

		
		public function move(x : int, y : int) : void
		{
			this.x = x;
			this.y = y;
		}

		
		public function removeAllChildren() : void
		{
			while (numChildren > 0) {
				removeChildAt(0);
			}
		}

		
		public function addChildren(...args ) : void
		{
			for each (var child : DisplayObject in args) {
				addChild(child);					
			}
		}

		
		public function removeChildren(...args ) : void
		{
			for each (var child : DisplayObject in args) {
				removeChild(child);					
			}
		}

		
		public function destroyChild(child : DisplayObject) : void
		{
			try {
				child["destroy"]();
			}catch(any : *) {
			}
			if(child.parent)
			{
				child.parent.removeChild(child);
			}
		}	

		
		public function updateView() : void
		{
		}

		
		/****************************************
		 *				GETTER-SETTER
		 ****************************************/
		protected function set resizeHandler(onResize : Function) : void
		{
			if(_resizeHandler != null)
			{
				if(stage)
					stage.removeEventListener(Event.RESIZE, _resizeHandler);
			}
			_resizeHandler = onResize;
			if(stage)
				stage.addEventListener(Event.RESIZE, _resizeHandler, false, 0, true);
		}

		
		public function get children() : Array
		{
			var i : int = -1;
			var array : Array = [];
			while(++i < numChildren) {
				array[i] = getChildAt(i);
			}
			return array;
		}

		
		public function get scale() : Number
		{
			return (scaleX >= scaleY) ? scaleX : scaleY;
		}

		
		public function set scale(value : Number) : void
		{
			scaleX = scaleY = value;
		}

		
		public function set stageX(value : Number) : void
		{
			x = value - stageX;
		}

		
		public function set stageY(value : Number) : void
		{
			y = value - stageY;
		}

		
		public function get stageX() : Number
		{
			return ((stage) ? getBounds(stage).x : 0);
		}

		
		public function get stageY() : Number
		{
			return ((stage) ? getBounds(stage).y : 0);
		}

		
		public function set enabled(enabled : Boolean) : void
		{
			_enabled = enabled;
		}

		
		public function get enabled() : Boolean
		{
			return _enabled;
		}

		
		public function get mouseOver() : Boolean
		{
			if (!stage)
                return false;
			var area : Sprite = (hitArea) ? hitArea : this;
			return area.getBounds(stage).contains(stage.mouseX, stage.mouseY);
		}

		
		public function get destroyed() : Boolean
		{
			return _destroyed;
		}

		
		public function set state(state : *) : void
		{
			_state = state;
			dispatchCoreEvent(CoreEvent.STATE_CHANGED, _state);
		}

		
		public function get state() : *
		{
			return _state;
		}
	}
}